﻿using System;


namespace DailyFx.AI
{

	public interface IBlock : IEquatable <IBlock>, IComparable<IBlock>
							, ICopyable	<IBlock>, ICloneable<IBlock>
	{
		/// <summary>
		///		Gets the category identifier .
		/// </summary>
		Guid Guid { get; }


		/// <summary>
		///		Gets the human-readable label text  .
		/// </summary>
		String Label { get; }


		/// <summary>
		///		Gets the version .
		/// </summary>
		Int32 Version { get; }

	}


	public abstract class Block : IBlock
	{
		/// <summary>
		///		
		/// </summary>
		public abstract Guid Guid { get; }

		/// <summary>
		/// 
		/// </summary>
		public abstract String Label { get; }

		/// <summary>
		///		Gets or sets the version .
		/// </summary>
		public abstract Int32 Version { get; set; }




		/// <summary>
		///		Indicates if the 2 blocks represent the same thing .
		/// </summary>
		public virtual bool Equals ( IBlock other )
		{
			return this.Guid == other.Guid && this.Label == other.Label;
		}

		/// <summary>
		///	
		/// </summary>
		public override bool Equals (object obj)
		{
			if ( !(obj is IBlock) ) return false;

			return base.Equals( obj as IBlock );
		}

		/// <summary>
		/// 
		/// </summary>
		public override int GetHashCode()
		{
			// Popular approach for Java .
			//
			// return this.Guid.GetHashCode() * 37 + this.Label.GetHashCode();


			// Generic approach provided by .Net framework .
			//
			return new { A = this.Guid, B = this.Label, }.GetHashCode();
		}

		/// <summary>
		///		
		/// </summary>
		public virtual int CompareTo ( IBlock other )
		{ 
			// 
			int i = this.Guid.CompareTo( other.Guid );
			if (i == 0)
				return this.Label.CompareTo(other.Label);
			else
				return i;
		}


		/// <summary>
		///		Clones a new instance of this <see cref="IBlock"/> .
		/// </summary>
		public abstract IBlock clone();


		/// <summary>
		///		Makes copy of this from the <param name="source"/>  .
		/// </summary>
		public abstract void copy( IBlock source );



		/// <summary>
		/// 
		/// </summary>
		public override string ToString()
		{
			return "Block: " + "[Guid] - " + this.Guid.ToString() + ", Label: " + this.Label; 
		}

	}

}
